﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml;
using intelliEssay.Core;
using intelliEssay.Core.DocumentStructure;

namespace intelliEssay.Checkers.DocumentKeyElementSequenceChecker
{
    public class intelliEssayDocumentKeyElementSequenceChecker : IEssayChecker
    {
        public void Run(Task tsk)
        {
            var keyElementSequence = tsk.documentStructure.documentElementSequence;
            var standardElementSequence = tsk.taskSetting.standardDocumentKeyElementSequence;
            for (int i = 0; i < keyElementSequence.documentKeyElmentSequence.Count() - 1; i++)
            {
                if (DocumentKeyElementSequence.Compare(keyElementSequence.documentKeyElmentSequence[i], keyElementSequence.documentKeyElmentSequence[i + 1], standardElementSequence) <= 0)
                {
                    var SmallerIndexCollection = keyElementSequence.documentKeyElmentSequence.Where<DocumentParts>(o =>
                        {
                            return  standardElementSequence.documentKeyElmentSequence.IndexOf(o) < standardElementSequence.documentKeyElmentSequence.IndexOf(keyElementSequence.documentKeyElmentSequence[i + 1]);
                        });
                    if (SmallerIndexCollection.Count() == 0)
                    {
                        continue;
                    }
                    var nearestButSmallerIdx = SmallerIndexCollection.Max<DocumentParts>(new Func<DocumentParts, int>(o =>
                           {
                               return standardElementSequence.documentKeyElmentSequence.IndexOf(o);
                           }));
                    DocumentParts target;
                    try
                    {
                        target = keyElementSequence.documentKeyElmentSequence[nearestButSmallerIdx];
                        if (nearestButSmallerIdx > standardElementSequence.documentKeyElmentSequence.IndexOf(keyElementSequence.documentKeyElmentSequence[i + 1]))
                        {
                            target = keyElementSequence.documentKeyElmentSequence[0];
                        }
                    }
                    catch
                    {
                        target = keyElementSequence.documentKeyElmentSequence[0];
                    }

                    string errorMsg = "错误关键字顺序:" + keyElementSequence.documentKeyElmentSequence[i + 1].ToLocalizedString(0) + "应当紧贴" + target.ToLocalizedString(0) + "之后出现";
                    tsk.AddEssayExceptionToEssayExceptionCollection(new EssayException(ExceptionType.ElementSequence, errorMsg, tsk.documentStructure.NoWherePointer, tsk, true));
                }
            }
            var undetectedKeyElements = standardElementSequence.documentKeyElmentSequence.Except<DocumentParts>(keyElementSequence.documentKeyElmentSequence);
            foreach (DocumentParts dp in undetectedKeyElements)
            {
                if (standardElementSequence.documentKeyElementParagraphDictionary[dp].GetAttributes().Where<OpenXmlAttribute>(o =>
                    {
                        return o.LocalName == "conditional";
                    }).Count() == 0)
                {
                    tsk.AddEssayExceptionToEssayExceptionCollection(new EssayException(ExceptionType.Element, "缺少关键元素" + dp.ToLocalizedString(0), tsk.documentStructure.NoWherePointer, tsk, true));
                }
            }
        }
        public void Cancel(Task tsk)
        {
            throw new NotImplementedException();
        }


        public string GetDescription(string cultureInfo)
        {
            return "Checks document key elements' orders, and ensures all required parts presence in the document.";
        }

        public string GetName(string cultureInfo)
        {
            return "Document Element Order Checker";
        }
    }
}
